package com.devops.admin.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.devops.admin.model.DOSOracleAwrReport;
import com.devops.admin.model.Pagination;
import com.devops.admin.model.TableResult;
import com.devops.admin.po.TimeRangePo;
import com.devops.admin.service.DOSOracleAwrReportService;
import com.devops.admin.mapper.DOSOracleAwrReportMapper;
import com.devops.admin.vo.DOSPageVo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* @author Dell
* @description 针对表【dos_oracle_awr_report】的数据库操作Service实现
* @createDate 2023-12-08 17:17:56
*/
@Service
public class DOSOracleAwrReportServiceImpl extends ServiceImpl<DOSOracleAwrReportMapper, DOSOracleAwrReport>
    implements DOSOracleAwrReportService {
    @Resource
    OSSClient ossClient;
    @Value("${aliyun.oss.bucket.name.devops}")
    String bucketName;
    @Value("${aliyun.oss.bucket.domain.devops}")
    String bucketDomain;
    @Override
    public String uploadOSS(MultipartFile file) {
        try {
            String fileName = file.getOriginalFilename();
            Pattern pattern = Pattern.compile("\\d{14}");
            Matcher matcher = pattern.matcher(fileName);
            if (matcher.find()) {
                String dateTimeString = matcher.group();
                // 提取匹配的日期时间字符串
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
                // 使用SimpleDateFormat解析日期时间
                Date date = dateFormat.parse(dateTimeString);
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(date);
                int year = calendar.get(Calendar.YEAR);
                int month = calendar.get(Calendar.MONTH) + 1;
                int day = calendar.get(Calendar.DAY_OF_MONTH);
                int hour = calendar.get(Calendar.HOUR_OF_DAY);

                String keyTemplate = "devops/oralce/awr/reports/{}/{}/{}/{}/{}/{}";
                String key = StrUtil.format(keyTemplate, year, month, day, hour, UUID.randomUUID(), fileName);
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setCacheControl("max-age=31536000");
                ossClient.putObject(bucketName, key, file.getInputStream(), metadata);

                String url = StrUtil.format("{}/{}", bucketDomain, key);
                LocalDateTime periodStart = DateUtil.truncate(DateUtil.offsetHour(date, -1), DateField.HOUR).toTimestamp().toLocalDateTime();
                DOSOracleAwrReport dosOracleAwrReport = DOSOracleAwrReport.builder()
                        .url(url)
                        .periodStart(periodStart)
                        .periodEnd(periodStart.plusHours(1))
                        .build();
                this.save(dosOracleAwrReport);
                return url;
            }
        } catch (ParseException | IOException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    @Override
    public String uploadOSSV2(MultipartFile file) {
        try {
            String fileName = file.getOriginalFilename();
            Pattern pattern = Pattern.compile("_(\\d{12})_(\\d{12})\\.html");
            Matcher matcher = pattern.matcher(fileName);

            if (matcher.find()) {
                String startDateTimeStr = matcher.group(1);
                String endDateTimeStr = matcher.group(2);

                // 定义日期时间格式
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmm");
                // 使用SimpleDateFormat解析日期时间
                Date startDateTime = dateFormat.parse(startDateTimeStr);
                Date endDateTime = dateFormat.parse(endDateTimeStr);
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(startDateTime);
                int year = calendar.get(Calendar.YEAR);
                int month = calendar.get(Calendar.MONTH) + 1;
                int day = calendar.get(Calendar.DAY_OF_MONTH);
                int hour = calendar.get(Calendar.HOUR_OF_DAY);

                String keyTemplate = "devops/oralce/awr/reports/{}/{}/{}/{}/{}/{}";
                String key = StrUtil.format(keyTemplate, year, month, day, hour, UUID.randomUUID(), fileName);
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setCacheControl("max-age=31536000");
                ossClient.putObject(bucketName, key, file.getInputStream(), metadata);

                String url = StrUtil.format("{}/{}", bucketDomain, key);
                LocalDateTime periodStart = DateUtil.truncate(startDateTime, DateField.HOUR).toTimestamp().toLocalDateTime();
                LocalDateTime periodEnd = DateUtil.truncate(endDateTime, DateField.HOUR).toTimestamp().toLocalDateTime();
                DOSOracleAwrReport dosOracleAwrReport = DOSOracleAwrReport.builder()
                        .url(url)
                        .periodStart(periodStart)
                        .periodEnd(periodEnd)
                        .build();
                this.save(dosOracleAwrReport);
                return url;
            }
        } catch (ParseException | IOException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    @Override
    public List<DOSOracleAwrReport> getLatestReport(int size) {
        return this.lambdaQuery().orderByDesc(DOSOracleAwrReport::getPeriodStart).last("limit " + size).list();
    }

    @Override
    public TableResult<DOSOracleAwrReport> getReportList(DOSPageVo pageVo, TimeRangePo timeRangePo) {
        Page<DOSOracleAwrReport> page = new Page<>(pageVo.getPageNum(), pageVo.getPageSize());
        List<DOSOracleAwrReport> list = this.lambdaQuery()
                .ge(timeRangePo.getStartTime() != null, DOSOracleAwrReport::getPeriodStart,
                        timeRangePo.getStartTime())
                .lt(timeRangePo.getEndTime() != null, DOSOracleAwrReport::getPeriodStart,
                        timeRangePo.getEndTime())
                .orderByDesc(DOSOracleAwrReport::getPeriodStart)
                .page(page)
                .getRecords();
        Pagination p = Pagination.builder().pageNum(page.getCurrent()).pageSize(page.getSize()).total(page.getTotal()).build();
        return new TableResult<>(list, p);
    }
}




